﻿// Demo-cpp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

//说明
//TIME:  2021/2/5
//gitee: https://gitee.com/king66666/juzhi_tcp_sdk
//橘子sdk c++ 接入例子

//依赖库
//vcpkg install opensll
//vcpkg install thrift

#include <iostream>
#include <memory>

#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <openssl/md5.h>
#include <cpr/cpr.h>

#include "../../../libs/gen-cpp/Jz.h"
#include "_sstream.h"

using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;




class CppJzClient :public JzClient
{
public:
	//继承父类构造函数
	CppJzClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) :JzClient(prot) {};
	CppJzClient(std::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, std::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) :JzClient(iprot, oprot) {};
	~CppJzClient() {};

private:

	//全局 Token
	std::string G_Token;

	//软件密钥 appkey
	const std::string APPKEY = "16D4E40EA985A2B2E0D5105DB830A1CB";
	const int32_t APPID = 1;
	const int32_t VERID = 1;

private:
	//GetMyIP 获取本机IP
	std::string GetMyIP() {
		cpr::Response r = cpr::Get(cpr::Url{ "http://members.3322.org/dyndns/getip" });
		assert(r.status_code == 200);
		return r.text.substr(0, r.text.size() - 1);
	}

	//getTimeStamp 时间戳
	long long getTimeStamp(bool _13)
	{
		auto timestamp = std::chrono::system_clock::now().time_since_epoch().count();
		return _13 ? timestamp / 10000 : timestamp / 10000000;
	}

	std::string md5(std::string str) {
		unsigned char tmpbuff[MD5_DIGEST_LENGTH];
		MD5((const unsigned char*)str.c_str(), str.length(), tmpbuff);

		std::string result;
		for (size_t i = 0; i < 16; i++)
		{
			char tmpchar[3]{ 0 };
			sprintf(tmpchar, "%02X", tmpbuff[i]);
			result += tmpchar;
		}

		return result;
	}
public:

	//APP初始化
	//此处Token 参数必须为APPKEY
	void TestAppInit() {
		AppInitReq req;
		AppInitRes res;

		req.app_id = APPID;
		req.ver_id = VERID;
		req.public_req.token = APPKEY;
		req.public_req.client_ip = GetMyIP();
		req.public_req.timestamp = getTimeStamp(false);

		//调用父类接口
		AppInit(res, req);

		if (res.err.err_code == 400)
		{
			printf("AppInit ErrMsg %s", string_convert::UTF8ToANSI(res.err.err_msg.c_str()).c_str());
		}
		else {
			printf("AppInit \r\nLastVer %s \r\nUpdate %d \r\nBulletin %s \r\nMd5 %s\n",
				res.last_ver.c_str(),
				res.update,
				string_convert::UTF8ToANSI(res.bulletin.c_str()).c_str(),
				res.md5.c_str());

			G_Token = res.token;
		}

	}

	//创建用户
	void TestCreateUser(string email, string username, string password, string mac, string cdkey) {
		UserCreateReq req;
		UserCreateRes res;

		req.email = email;
		req.mac = md5(mac);
		req.user = username;
		req.pwd = md5(password);
		req.cdkey = cdkey;
		req.public_req.client_ip = GetMyIP();
		req.public_req.token = G_Token;
		req.public_req.timestamp = getTimeStamp(false);

		UserCreate(res, req);
		if (res.err.err_code == 400)
		{
			printf("TestCreateUser ErrMsg %s\n", string_convert::UTF8ToANSI(res.err.err_msg.c_str()).c_str());
		}
		else {
			printf("TestCreateUser Msg %s\n", string_convert::UTF8ToANSI(res.msg.c_str()).c_str());
		}

	}

	//用户登录
	void TestUserLogin(string username, string password, string mac) {
		UserLoginReq req;
		UserLoginRes res;

		req.user = username;
		req.pwd = md5(password);
		req.mac = md5(mac);
		req.public_req.client_ip = GetMyIP();
		req.public_req.token = G_Token;
		req.public_req.timestamp = getTimeStamp(false);

		UserLogin(res, req);
		if (res.err.err_code == 400)
		{
			printf("TestUserLogin ErrMsg %s\n", string_convert::UTF8ToANSI(res.err.err_msg.c_str()).c_str());
		}
		else {
			printf("TestUserLogin 到期时间 %s\n时间戳 %llu\n注册邮箱 %s\n剩余点数 %d\n是否签到 %d\n",
				res.finaltime.c_str(),
				res.finaltime_uinx,
				res.email.c_str(),
				res.tally,
				res.sign);

			G_Token = res.token;
		}
	}

	//心跳  刷新TOKEN
	void TestGetUserStatus() {
		GetUserStatusReq req;
		GetUserStatusRes res;

		req.public_req.client_ip = GetMyIP();
		req.public_req.token = G_Token;
		req.public_req.timestamp = getTimeStamp(false);

		GetUserStatus(res, req);
		if (res.err.err_code == 400)
		{
			printf("TestUserLogin ErrMsg %s\n", string_convert::UTF8ToANSI(res.err.err_msg.c_str()).c_str());
		}
		else {
			printf("TestUserLogin 到期时间 %s\n时间戳 %llu\n在线人数 %d\n剩余点数 %d\n",
				res.finaltime.c_str(),
				res.finaltime_uinx,
				res.online,
				res.tally);

			G_Token = res.token;
		}
	}
};


int main()
{
	std::shared_ptr<TTransport> socket(new TSocket("www.jzserver.com", 9898));
	std::shared_ptr<TTransport> transport(new TBufferedTransport(socket, 0x1000));
	std::shared_ptr<TProtocol> protocol(new TCompactProtocol(transport));
	transport->open();
	CppJzClient client(protocol);

	try
	{
		printf("\nTestAppInit\n");
		client.TestAppInit();

		printf("\nTestCreateUser\n");
		client.TestCreateUser("king6666@gmail.com", "king666666", "123456", "wueew vhqbkvbqkvew", "D44FE84EEF1CC9A2EF2AC792830CBE41");

		printf("\nTestCreateUser\n");
		client.TestUserLogin("king666666", "123456", "wueew vhqbkvbqkvew");

		printf("\nTestGetUserStatus\n");
		client.TestGetUserStatus();	
	}
	catch (TException& tx)
	{
		cout << "ERROR: " << tx.what() << endl;
	}

	transport->close();
}

